﻿using Abp.Domain.Entities;
using Abp.Domain.Repositories;
using GN.Pay.Core.Entities;
using GN.Pay.Core.Exceptions;
using GN.Pay.Core.Repositories;
using GN.Pay.TradeChannel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static GN.Pay.Core.Consts.ServiceConstant;

namespace GN.Pay.Core.Services.Impl
{
    /// <summary>
    /// 交易通道申请服务
    /// </summary>
    public abstract class ATradeChannelApplyService : APayService
    {
        /// <summary>
        /// 
        /// </summary>
        protected ATradeChannelApplyService()
        {

        }

        /// <summary>
        /// 调用申请
        /// </summary>
        /// <typeparam name="TApply"></typeparam>
        /// <typeparam name="TPrimaryKey"></typeparam>
        /// <typeparam name="TRepository"></typeparam>
        /// <param name="apply"></param>
        /// <param name="repository"></param>
        /// <param name="opName"></param>
        protected void CallApply<TApply, TPrimaryKey, TRepository>(
            TApply apply,
            TRepository repository,
            string opName)
            where TApply : class, IApplyState, IEntity<TPrimaryKey>
            where TRepository : IPayRepository<TApply, TPrimaryKey>
        {           
            apply.ApplyState = TradeApplyState.Executeing;
            apply.ApplyStateMessage = "正在" + opName + "，等待通知";
            apply.LastSubmitTime = DateTime.Now;
            repository.Update(apply);
            repository.SaveChanges();           
        }

        /// <summary>
        /// 调用申请结果
        /// </summary>
        /// <typeparam name="TApply"></typeparam>
        /// <typeparam name="TPrimaryKey"></typeparam>
        /// <typeparam name="TResult"></typeparam>
        /// <typeparam name="TRepository"></typeparam>
        /// <param name="apply"></param>
        /// <param name="result"></param>
        /// <param name="repository"></param>
        /// <param name="opName"></param>
        /// <param name="completeNotifyService"></param>
        protected void CallApplyResult<TApply, TPrimaryKey, TResult, TRepository>(
            TApply apply,
            TResult result,
            TRepository repository,
            string opName,
            Action<ITradeNotifyService, TResult> completeNotifyService)
            where TApply : class, IApplyState, IEntity<TPrimaryKey>
            where TResult : ITradeApplyResult
            where TRepository : IPayRepository<TApply, TPrimaryKey>
        {
            switch (result.ResultState)
            {
                
                case TradeApplyResultState.Apply_Error:
                    apply.ApplyState = TradeApplyState.Execute_Error;
                    apply.ApplyStateMessage = result.ResultStateMessage;
                    apply.LastSubmitTime = DateTime.Now;
                    repository.Update(apply);
                    break;

                case TradeApplyResultState.Info_Error:
                    apply.ApplyState = TradeApplyState.Execute_Info_Error;
                    apply.ApplyStateMessage = result.ResultStateMessage;
                    apply.LastSubmitTime = DateTime.Now;
                    repository.Update(apply);
                    repository.SaveChanges();
                    if (completeNotifyService != null)
                    {
                        var notifyService = this.Resolve<ITradeNotifyService>();
                        completeNotifyService(notifyService, result);
                    }
                    break;

                case TradeApplyResultState.Apply_Success_Wiat_Notify:
                   // apply.ApplyState = TradeApplyState.Executeing;
                   // apply.ApplyStateMessage = "正在" + opName + "，等待通知";
                  //  apply.LastSubmitTime = DateTime.Now;
                  //  repository.Update(apply);
                    break;
                case TradeApplyResultState.Balance_Insufficient_Error:
                    apply.ApplyState = TradeApplyState.Execute_Balance_Error;
                    apply.ApplyStateMessage = "账户余额不足，无法" + opName;
                    apply.LastSubmitTime = DateTime.Now;
                    repository.Update(apply);
                    break;
                case TradeApplyResultState.Complete_Success:
                    apply.ApplyState = TradeApplyState.Execute_Success;
                    apply.ApplyStateMessage = opName + "成功";
                    apply.LastSubmitTime = DateTime.Now;
                    repository.Update(apply);
                    repository.SaveChanges();
                    if (completeNotifyService != null)
                    {
                        var notifyService = this.Resolve<ITradeNotifyService>();
                        completeNotifyService(notifyService, result);
                    }
                    break;
                default:
                    PayExceptionUtils.ThrowPaySystemException(opName + "申请结果类型为 " + result.ResultState + " 无法处理");
                    break;
            }
        }
    }
}
